package Model;

import java.util.ArrayList;

import View.IKiirhato;
import View.IMegjelenitheto;
import View.Megjelenitendo;

/**
 * 
 * A mező egy oszthatatlan pozíció a játéktéren. A mezők ismerik szomszédaikat, és azoknak hozzájuk képest való elhelyezkedését.
 * Minden mezőnek hat szomszédja van, emellett a mező tudja hogy milyen entitások vannak rajta,
 * valamint hogy róla melyik szomszédos mezőre kell lépni hogy közelebb kerüljünk a legközelebbi ételhez.
 *
 */

public class Mezo implements IIttVan, IKiirhato, IMegjelenitheto
{
	/** A Mezővel szomszédos Mezők listája. */
	private ArrayList<Mezo> szomszedMezok;
	/** Egy olyan Mező amelyre lépve közelebb kerülünk a legközelebbi Kajához. */
	private Mezo legkozelebbiKajaIranya;
	
	private static int _azonosito;
	
	private int azonosito;

	static
	{
		_azonosito = 1;
	}
	
	public Mezo()
	{
		azonosito = _azonosito++;
		szomszedMezok = new ArrayList<Mezo>();
	}
	
	public int getAzonosito()
	{
		return azonosito;
	}

	public Mezo getLegkozelebbiKajaIranya() {
		return legkozelebbiKajaIranya;
	}

	public void setLegkozelebbiKajaIranya(Mezo legkozelebbiKajaIranya) {
		this.legkozelebbiKajaIranya = legkozelebbiKajaIranya;
	}

	/** A Mezőn lévő Entitások listája. */
	private ArrayList<Entitas> entitasok = new ArrayList<Entitas>();

	/**
	 * A Mező Entitásokat tartalmazó listájába felvesz egy újabb Entitást,
	 * ezzel a Mezőre helyezve azt.
	 * @param e Egy Entitás objektum, amit ide szeretnénk rakni a Mezőre.
	 */
	

	
	public void rarak(Entitas e)
	{
		entitasok.add(e); // hozzaadja az entitast
	}

	/**
	 * A Mező Entitásokat tartalmazó listájából kivesz egy már ottlevő Entitást,
	 * ezzel a Mezőre helyezve azt.
	 * @param e Egy Entitás objektum, amit le szeretnénk venni a Mezőről.
	 */
	public void levesz(Entitas e)
	{
		entitasok.remove(e); // leszedi az entitast
	}

	/**
	 * Végighívja az adott Mezőn tartózkodó Entitásokon ugyanezen paraméterrel ugyanezt a függvényt.
	 * @param hangya Egy Hangya objektum, aki hívta a függvényt.
	 */
	public void ittVan(Hangya hangya)
	{
		// a mezőn levő összes entitáson broadcastolunk
		for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
		{
			entitasok.get(i).ittVan(hangya);
			if(prevSize > entitasok.size()) i--;
			prevSize = entitasok.size();
		}
	}

	/**
	 * Végighívja az adott Mezőn tartózkodó Entitásokon ugyanezen paraméterrel ugyanezt a függvényt.
	 * @param kavics Egy Kavics objektum, aki hívta a függvényt.
	 */
	public void ittVan(Kavics kavics)
	{
		for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
		{
			entitasok.get(i).ittVan(kavics);
			if(prevSize > entitasok.size()) i--;
			prevSize = entitasok.size();
		}
	}

	/**
	 * Végighívja az adott Mezőn tartózkodó Entitásokon ugyanezen paraméterrel ugyanezt a függvényt.
	 * @param hsun Egy Hangyászsün objektum, aki hívta a függvényt.
	 */
	public void ittVan(HangyaszSun hsun)
	{
		// a mezőn levő összes entitáson broadcastolunk
		for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
		{
			entitasok.get(i).ittVan(hsun);
			if(prevSize > entitasok.size()) i--;
			prevSize = entitasok.size();
		}
	}

	/**
	 * Végighívja az adott Mezőn tartózkodó Entitásokon ugyanezen paraméterrel ugyanezt a függvényt.
	 * @param szS Egy SzagSpray objektum, ami hívta a függvényt.
	 */
	public void ittVan(SzagSpray szS)
	{
		// a mezőn levő összes entitáson broadcastolunk
		for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
		{
			entitasok.get(i).ittVan(szS);
			if(prevSize > entitasok.size()) i--;
			prevSize = entitasok.size();
		}
	}

	/**
	 * Végighívja az adott Mezőn tartózkodó Entitásokon ugyanezen paraméterrel ugyanezt a függvényt.
	 * @param olS Egy ÖlőSpray objektum, ami hívta a függvényt.
	 */
	public void ittVan(OloSpray olS)
	{
		// a mezőn levő összes entitáson broadcastolunk
		for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
		{
			entitasok.get(i).ittVan(olS);
			if(prevSize > entitasok.size()) i--;
			prevSize = entitasok.size();
		}
	}

	/**
	 * Végighívja az adott Mezőn tartózkodó Entitásokon ugyanezen paraméterrel ugyanezt a függvényt.
	 * @param sz Egy Szag objektum, ami hívta a függvényt.
	 */
	public void ittVan(Szag sz)
	{
		// a mezőn levő összes entitáson broadcastolunk
		for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
		{
			entitasok.get(i).ittVan(sz);
			if(prevSize > entitasok.size()) i--;
			prevSize = entitasok.size();
		}
	}
	
	@Override
	public void ittVan(Hangyaboly hangyaboly) {
		// a mezőn levő összes entitáson broadcastolunk
				for(int i = 0, prevSize = entitasok.size(); i < entitasok.size(); i++)
				{
					entitasok.get(i).ittVan(hangyaboly);
					if(prevSize > entitasok.size()) i--;
					prevSize = entitasok.size();
				}
	}
	
	/**
	 * A teszteléshez szükséges függvény, beállítja a szomszéd Mezők listát.
	 * @param list Egy Mezőket tartalmazó lista.
	 */
	public void setSzomszedMezok(ArrayList<Mezo> list)
	{
		szomszedMezok = list;
	}

	/**
	 * A teszteléshez szükséges függvény.
	 * @return A szomszéd Mezők listája.
	 */
	public ArrayList<Mezo> getSzomszedok()
	{
		return szomszedMezok;
	}
	
	/**
	 * A teszteléshez szükséges függvény.
	 * @return A Mezőn lévő Entitások listája.
	 */
	public ArrayList<Entitas> getEntitasok()
	{
		return entitasok;
	}
	
	public String kiir()
	{
		return "M(" + azonosito + ")";
	}

	@Override
	public Megjelenitendo Megjelenit()
	{
		Megjelenitendo m = new Megjelenitendo();
		for(Entitas e : entitasok)
		{
			Megjelenitendo temp = e.Megjelenit();
			if(temp.getBackgroundColor() != null) m.setBackgroundColor(temp.getBackgroundColor());
			if(temp.getDotColor() != null) m.setDotColor(temp.getDotColor());
		}
		m.setMezoID(azonosito);
		return m;
	}
}